package com.itany.corejava.code13_jdbc;


import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 石小俊
 * @date 2023年05月25日 15:02
 */
public class Test01_快速入门 {

    public static final String JDBC_URL = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";

    public static void main(String[] args) {
         User user = new User("jack", "123456", "13912345678", "江苏-南京");
         insertUser(user);

//        List<User> users = selectAll();
//        for (User user : users) {
//            System.out.println(user);
//        }

//        User user = new User(2,"tom","666666","13212345678","江苏-苏州");
//        updateUser(user);

//        deleteByPrimaryKey(2);

//        User user = selectByPrimaryKey(1);
//        System.out.println(user);
    }

    /**
     * 添加用户信息
     *
     * @param user
     */
    public static void insertUser(User user) {
        Connection conn = null;
        Statement st = null;
        try {
            // 1.注册驱动
            // 注册由数据库厂商所提供的驱动
            // 根据数据库类型不同、版本不同,驱动所在包名与类名都有可能不同
            // 此处以MySQL5的版本为例
            // 注册驱动是通过反射来实现
            // 通过Class.forName("包名.类名")来注册驱动
            Class.forName("com.mysql.jdbc.Driver");

            // 2.获取连接
            // 连接到指定的数据库中,由数据库厂商提供了连接方式
            // 参数一:连接到数据库的url地址
            // 对于MySQL而言,其url地址格式为 jdbc:mysql://mysql服务的ip地址:端口号/库名
            // ip地址指的是MySQL服务器所在的计算机ip地址,可以使用本机地址:127.0.0.1或者localhost
            // 端口号默认为:3306
            // jdbc:mysql://127.0.0.1:3306/jdbc
            // 在java访问数据库时,可能会出现乱码问题
            // 在url末尾指定编码
            // ?useUnicode=true&characterEncoding=utf-8
            // 参数二:MySQL的账号
            // 参数三:MySQL的密码
            // conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc","root","");
            conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc?useUnicode=true&characterEncoding=utf-8", "root", "");

            // 3.获取状态集
            // 用于操作数据库
            st = conn.createStatement();

            // 4.执行sql
            // 准备一个需要执行的sql语句
            String sql = "insert into t_user(username,password,phone,address) values('" + user.getUsername() + "','" + user.getPassword() + "','" + user.getPhone() + "','" + user.getAddress() + "')";
            // 执行DML操作。即:增删改操作
            // 返回值为:受到影响的数据的行数
            int row = st.executeUpdate(sql);
            System.out.println("Query ok," + row + " rows affected");

            // 5.处理结果集,仅限查询操作
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("找不到驱动");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("数据库访问失败");
        } finally {
            // 6.释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
        }
    }

    /**
     * 查询所有用户信息
     * @return
     */
    public static List<User> selectAll() {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        List<User> users = new ArrayList<>();
        try {
            // 1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8", "root", "");
            // 3.获取状态集
            st = conn.createStatement();
            // 4.执行sql
            String sql = "select id,username,password,phone,address from t_user";
            // 执行查询操作
            // 此时方法的返回值是数据库查询的结果集
            // 在JDBC中,数据库查询的结果集由数据库厂商封装成了ResultSet对象
            rs = st.executeQuery(sql);

            // 5.处理结果集
            // 需要将数据库查询的结果集映射成Java对象
            // 查询的结果集中每一行数据映射成一个Java对象
            // 如果存在多行数据,映射的是一个Java对象集合
            // ResultSet对象提供了next()方法,用于读取下一行数据
            // 需要判断下一行是否有数据,如果有数据则将这一行数据映射成一个Java对象
            while (rs.next()) {
                // 只要下一行有数据,就需要处理。直到下一行没有数据为止
                // 每读取一行数据,映射成一个Java对象
                User user = new User();
                // 通过结果集提供的getXxx(int columnIndex)或者getXxx(String columnLabel)来进行转换
                // getXxx(int columnIndex):获取第几列的数据
                // getXxx(String columnLabel):获取指定列名的数据
                // 开发中字段可能比较多,因此如果使用第几列容易混乱,建议使用列名
                // 此处表示将查询结果第一列的数据转换成Java中int类型
                int id = rs.getInt(1);
                // 此处表示将查询结果中列名为username的数据转换成Java中String类型
                String username = rs.getString("username");
                user.setId(id);
                user.setUsername(username);
                user.setPassword(rs.getString("password"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));

                // 映射完成之后只是映射了一行数据
                // 查询结果中可能包含了无数行数据,每一行数据对应一个Java对象
                // 因此,可以通过一个集合接收这些映射好的Java对象
                // 每映射一次,生成一个Java对象,将生成的Java对象添加到指定的集合中
                users.add(user);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6.释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 将映射完成的对象集合返回
        return users;
    }

    /**
     * 修改用户信息
     * @param user
     */
    public static void updateUser(User user) {
        Connection conn = null;
        Statement st = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(JDBC_URL, "root", "");
            st = conn.createStatement();
            String sql = "update t_user set username = '" + user.getUsername() + "',password = '" + user.getPassword() + "',phone = '" + user.getPhone() + "',address = '" + user.getAddress() + "' where id = '" + user.getId() + "'";
            int row = st.executeUpdate(sql);
            System.out.println("Query ok," + row + " rows affected");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("驱动不存在");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("数据库访问异常");
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
        }
    }

    /**
     * 根据主键删除指定用户信息
     * @param primaryKey
     */
    public static void deleteByPrimaryKey(Integer primaryKey) {
        Connection conn = null;
        Statement st = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(JDBC_URL, "root", "");
            st = conn.createStatement();
            String sql = "delete from t_user where id = " + primaryKey + "";
            int row = st.executeUpdate(sql);
            System.out.println("Query ok," + row + " rows affected");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("驱动不存在");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("数据库访问异常");
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("释放资源出错");
                }
            }
        }
    }

    /**
     * 根据主键查询用户信息
     * @param primaryKey
     * @return
     */
    public static User selectByPrimaryKey(Integer primaryKey) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        User user = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(JDBC_URL, "root", "");
            st = conn.createStatement();
            String sql = "select id,username,password,phone,address from t_user where id = " + primaryKey + "";
            rs = st.executeQuery(sql);
            // 根据主键查询返回的信息最多只有一条
            // 因此,此处也可以使用if判断
            if (rs.next()) {
                // 映射对象
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setPhone(rs.getString("phone"));
                user.setAddress(rs.getString("address"));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("驱动不存在");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("数据库访问异常");
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (st != null) {
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return user;
    }
}
